 
package net.jforum.view.forum;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import net.jforum.Command;
import net.jforum.JForum;
import net.jforum.JForumExecutionContext;
import net.jforum.SessionFacade;
import net.jforum.TestTools;
import net.jforum.dao.DataAccessDriver;
import net.jforum.dao.ForumDAO;
import net.jforum.dao.ModerationDAO;
import net.jforum.entities.Forum;
import net.jforum.entities.MostUsersEverOnline;
import net.jforum.entities.UserSession;
import net.jforum.repository.ForumRepository;
import net.jforum.repository.ModeratorRepository;
import net.jforum.repository.SecurityRepository;
import net.jforum.repository.SummaryRepository;
import net.jforum.repository.TopicRepository;
import net.jforum.security.SecurityConstants;
import net.jforum.util.CommonUtil;
import net.jforum.util.I18n;
import net.jforum.util.SEOUtil;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;
import net.jforum.util.preferences.TemplateKeys;
import net.jforum.view.admin.ModerationAction;
import net.jforum.view.forum.common.ForumCommon;
import net.jforum.view.forum.common.PostCommon;
import net.jforum.view.forum.common.TopicsCommon;
import net.jforum.view.forum.common.ViewCommon;

/**
 * @author Rafael Steil
 * @version $Id: ForumAction.java,v 1.76 2007/09/03 12:24:32 rafaelsteil Exp $
 */
public class ForumAction extends Command
{
	/**
	 * List all the forums (first page of forum index)?
	 */
	private static Logger logger = Logger.getLogger(ForumAction.class);
	public void list()
	{
        
		this.setTemplateName(TemplateKeys.FORUMS_LIST);
		this.context.put("allCategories", ForumCommon.getAllCategoriesAndForums(true));
		this.context.put("topicsPerPage", new Integer(SystemGlobals.getIntValue(ConfigKeys.TOPICS_PER_PAGE)));
		this.context.put("rssEnabled", SystemGlobals.getBoolValue(ConfigKeys.RSS_ENABLED));
     	SimpleDateFormat df = new SimpleDateFormat(SystemGlobals.getValue(ConfigKeys.DATE_TIME_FORMAT));
		GregorianCalendar gc = new GregorianCalendar();
		this.context.put("now", df.format(gc.getTime()));
		this.context.put("lastVisit", df.format(SessionFacade.getUserSession().getLastVisit()));
		this.context.put("forumRepository", new ForumRepository());//因为ForumRepository中的方法和变量都是静态的
        this.context.put("moderatorRepository", new ModeratorRepository());
    	int aid = SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID);
     	UserSession currentUser = SessionFacade.getUserSession();
     	this.context.put("summaryRepository", new SummaryRepository());
     	this.context.put("totalTopics", TopicRepository.getTopicsCount());

		if (currentUser.getUserId() == aid) {
			String lang = this.request.getParameter("lang");

			if (lang != null && I18n.languageExists(lang)) {
				currentUser.setLang(lang);
			}
		}

	}

	public void moderation()
	{
		this.context.put("openModeration", true);
		this.show();
	}

	/**
	 * Display all topics in a forum
	 */
	public void show()
	{
		int forumId = this.request.getIntParameter("forum_id");
//		ForumDAO fm = DataAccessDriver.getInstance().newForumDAO();
		
		// The user can access this forum?
		Forum forum = ForumRepository.getForum(forumId);

		if (forum == null || !ForumRepository.isCategoryAccessible(forum.getCategoryId())) {
			new ModerationHelper().denied(I18n.getMessage("ForumListing.denied"));
			return;
		}

		int start = ViewCommon.getStartPage();
		List tmpTopics=null;
		String selectIndexId=this.request.getParameter("indexId");

		if("1".equals(selectIndexId)){
			tmpTopics=TopicsCommon.topicsByForumAndTopicTime(forumId, start);
		}else if("2".equals(selectIndexId)){
			tmpTopics= TopicsCommon.topicsByForumAndReplyCount(forumId, start);	
		}else {
			tmpTopics= TopicsCommon.topicsByForum(forumId, start);
		}
		if(StringUtils.isBlank(selectIndexId))
		   this.context.put("selectIndex", "0");
		else 
		   this.context.put("selectIndex",selectIndexId);
		
		this.setTemplateName(TemplateKeys.FORUMS_SHOW);

		// Moderation
		UserSession userSession = SessionFacade.getUserSession();
		boolean isLogged = SessionFacade.isLogged();
		boolean isModerator = userSession.isModerator(forumId);

		boolean canApproveMessages = (isLogged && isModerator 
			&& SecurityRepository.canAccess(SecurityConstants.PERM_MODERATION_APPROVE_MESSAGES));

		Map topicsToApprove = new HashMap();

		if (canApproveMessages) {
			ModerationDAO mdao = DataAccessDriver.getInstance().newModerationDAO();
			topicsToApprove = mdao.topicsByForum(forumId);
			this.context.put("postFormatter", new PostCommon());
		}

		this.context.put("topicsToApprove", topicsToApprove);

		this.context.put("attachmentsEnabled", SecurityRepository.canAccess(SecurityConstants.PERM_ATTACHMENTS_ENABLED,
		        Integer.toString(forumId))
		        || SecurityRepository.canAccess(SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD));

		this.context.put("topics", TopicsCommon.prepareTopics(tmpTopics));
		this.context.put("allCategories", ForumCommon.getAllCategoriesAndForums(false)); 
		this.context.put("forum", forum);
		this.context.put("rssEnabled", SystemGlobals.getBoolValue(ConfigKeys.RSS_ENABLED));
		this.context.put("pageTitle", SEOUtil.forumShowSEO(forum.getName()));
		this.context.put("canApproveMessages", canApproveMessages);
		this.context.put("replyOnly", !SecurityRepository.canAccess(SecurityConstants.PERM_REPLY_ONLY, Integer
		        .toString(forum.getId())));

		this.context.put("readonly", !SecurityRepository.canAccess(SecurityConstants.PERM_READ_ONLY_FORUMS, Integer
		        .toString(forumId)));
        
		 //订阅功能，删除
        //this.context.put("watching", fm.isUserSubscribed(forumId, userSession.getUserId()));

		// Pagination
		int topicsPerPage = SystemGlobals.getIntValue(ConfigKeys.TOPICS_PER_PAGE);
		int postsPerPage = SystemGlobals.getIntValue(ConfigKeys.POSTS_PER_PAGE);
		int totalTopics = forum.getTotalTopics();

		ViewCommon.contextToPagination(start, totalTopics, topicsPerPage);
		this.context.put("postsPerPage", new Integer(postsPerPage));

		TopicsCommon.topicListingBase();
		this.context.put("moderator", isModerator && isLogged );
		this.context.put("moderatorRepository", new ModeratorRepository());
	}

	// Make an URL to some action
	private String makeRedirect(String action)
	{
		String path = this.request.getContextPath() + "/forums/" + action + "/";
		String thisPage = this.request.getParameter("start");

		if (thisPage != null && !thisPage.equals("0")) {
			path += thisPage + "/";
		}

		String forumId = this.request.getParameter("forum_id");

		if (forumId == null) {
			forumId = this.request.getParameter("persistData");
		}

		path += forumId + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION);

		return path;
	}

	// Mark all topics as read
	public void readAll()
	{
		String forumId = this.request.getParameter("forum_id");
		
		if (forumId != null) {
			Map tracking = SessionFacade.getTopicsReadTimeByForum();
			
			if (tracking == null) {
				tracking = new HashMap();
			}
			
			tracking.put(new Integer(forumId), new Long(System.currentTimeMillis()));
			SessionFacade.setAttribute(ConfigKeys.TOPICS_READ_TIME_BY_FORUM, tracking);
			JForumExecutionContext.setRedirect(this.makeRedirect("show"));
			return;
		}
			JForumExecutionContext.setRedirect(this.request.getContextPath() + "/forums/list"
		        + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
	}

	// Messages since last visit
	public void newMessages()
	{
		this.request.addParameter("from_date", SessionFacade.getUserSession().getLastVisit());
		this.request.addParameter("to_date", new Date());

		SearchAction searchAction = new SearchAction(this.request, this.response, this.context);
		searchAction.newMessages();
		
		this.setTemplateName(TemplateKeys.SEARCH_NEW_MESSAGES);
	}

	public void approveMessages()
	{
		if (SessionFacade.getUserSession().isModerator(this.request.getIntParameter("forum_id"))) {
			new ModerationAction(this.context, this.request).doSave();
		}

		JForumExecutionContext.setRedirect(this.request.getContextPath() + "/forums/show/"
			+ this.request.getParameter("forum_id") + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
	}

	/**
	 * Action when users click on "watch this forum"
	 * It gets teh forum_id and userId, and put them into a watch_forum table in the database;
	 */
	public void watchForum()
	{
		int forumId = this.request.getIntParameter("forum_id");
		int userId = SessionFacade.getUserSession().getUserId();

		this.watchForum(DataAccessDriver.getInstance().newForumDAO(), forumId, userId);

		JForumExecutionContext.setRedirect(this.redirectLinkToShowAction(forumId));
	}

	public void banned()
	{
		this.setTemplateName(TemplateKeys.FORUMS_BANNED);
		this.context.put("message", I18n.getMessage("ForumBanned.banned"));
	}

	private String redirectLinkToShowAction(int forumId)
	{
		int start = ViewCommon.getStartPage();

		return this.request.getContextPath() + "/forums/show/" + (start > 0 ? start + "/" : "") + forumId
			+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION);
	}

	/**
	 * 
	 * @param dao ForumDAO
	 * @param forumId int
	 * @param userId int
	 */
	private void watchForum(ForumDAO dao, int forumId, int userId)
	{
		if (SessionFacade.isLogged() && !dao.isUserSubscribed(forumId, userId)) {
			dao.subscribeUser(forumId, userId);
		}
	}

	/**
	 * Unwatch the forum watched.
	 */
	public void unwatchForum()
	{
		if (SessionFacade.isLogged()) {
			int forumId = this.request.getIntParameter("forum_id");
			int userId = SessionFacade.getUserSession().getUserId();

			DataAccessDriver.getInstance().newForumDAO().removeSubscription(forumId, userId);

			String returnPath = this.redirectLinkToShowAction(forumId);

			this.setTemplateName(TemplateKeys.POSTS_UNWATCH);
			this.context.put("message", I18n.getMessage("ForumBase.forumUnwatched", new String[] { returnPath }));
		}
		else {
			this.setTemplateName(ViewCommon.contextToLogin());
		}
	}
}
